/*
 * Copyright (c) 2013-2018 上海汇数数据. All rights reserved.
 * @(#) CipherParamsKt.java 2018-08-06 17:26
 */

package cn.jh.common.core.crypto;

/**
 * 加密算法参数工具类。
 *
 * @author Fuchun
 * @since 1.0
 */
public class CipherParamsKt {

    /** 默认的 AES 算法参数。 */
    public static final SymmetricCipherParams DEFAULT_AES_PARAMS = aesBuilder().build();

    public static final SymmetricCipherParams DEFAULT_TRIPLE_DES_PARAMS = tripleDesBuilder().build();

    /**
     * AES algorithm cipher parameters:
     * <pre>
     * 1. `transformation`: `"AES/CBC/PKCS7Padding"`
     * 2. `provider`: "BC"  -\> BouncyCastle
     * 3. `keySize`: **`keySize`**
     * 4. `useFixedIvByKey`: true, iv = key(0, 16)
     * 5. `generateIv`: false
     * 6. `prependIv`: false
     * 7. `ivSize`: 128 bit
     * 8. `secureRandom`: default SecureRandom
     * </pre>
     */
    public static SymmetricCipherParams aesPkcs7(int keySize) {
        return aesBuilder()
                .setKeySize(keySize)
                .setTransformation(Transformation.aesOf(OprMode.CBC, PaddingSchema.PKCS7))
                .build();
    }

    /**
     * Return the DESede algorithm cipher parameters builder:
     * Default properties:
     * <pre>
     * 1. transformation: "DESede/ECB/PKCS5Padding"
     * 2. provider: "SunJCE"  -\> SunJCE
     * 3. keySize: 168 bit
     * 4. useFixedIvByKey: false
     * 5. generateIv: false
     * 6. prependIv: false
     * 7. ivSize: 128 bit
     * 8. secureRandom: default SecureRandom
     * </pre>
     */
    public static SymmetricCipherParams.Builder tripleDesBuilder() {
        return new SymmetricCipherParams.Builder()
                .setTransformation(Transformation.tripleDes())
                .setProvider(CipherKt.SUN_JCE)
                .setKeySize(KeyBit.KB_168.bit)
                .notGenerateIv()
                .notPrependIv()
                .useDefaultSecureRandom();
    }

    /**
     * Return the AES algorithm cipher parameters builder:
     * Default properties:
     * <pre>
     * 1. transformation: "AES/CBC/PKCS5Padding"
     * 2. provider: "BC"  -\> BouncyCastle
     * 3. keySize: 256 bit
     * 4. useFixedIvByKey: true, iv = key(0, 16)
     * 5. generateIv: false
     * 6. prependIv: false
     * 7. ivSize: 128 bit
     * 8. secureRandom: default SecureRandom
     * </pre>
     */
    public static SymmetricCipherParams.Builder aesBuilder() {
        return new SymmetricCipherParams.Builder()
                .setTransformation(Transformation.aesOf(OprMode.CBC, PaddingSchema.PKCS5))
                .setProvider(CipherKt.BOUNCY_CASTLE)
                .setKeySize(KeyBit.KB_256.bit)
                .useFixedIvByKey()
                .notGenerateIv()
                .notPrependIv()
                .useDefaultSecureRandom()
                ;
    }

    /**
     * Return the RSA algorithm cipher parameters builder:
     * Default properties:
     * <pre>
     * 1. transformation: `"RSA/ECB/PKCS1Padding"`
     * 2. signatureAlgorithm: "SHA1withRSA"
     * 3. secureRandom: default SecureRandom
     * 4. provider: "BC"  -\> BouncyCastle
     * </pre>
     */
    public static AsymmetricCipherParams.Builder rsaBuilder() {
        return new AsymmetricCipherParams.Builder()
                .setTransformation(Transformation.rsaOf(OprMode.ECB, PaddingSchema.PKCS1))
                .setProvider(CipherKt.BOUNCY_CASTLE)
                .useDefaultSecureRandom()
                .setSignatureAlgorithm("SHA1withRSA");
    }

    public static SymmetricCipherParams pbe(String algorithm) {
        return new SymmetricCipherParams.Builder()
                .setTransformation(Transformation.pbeOf(algorithm))
                .setKeySize(-1)
                .setIvSize(8)
                .useFixedIvByKey()
                .notGenerateIv()
                .notPrependIv()
                .useDefaultSecureRandom()
                .build();
    }

    private CipherParamsKt() {}
}
